package com.shujia.core

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Demo8GroupByKey {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    conf.setMaster("local")
    conf.setAppName("groupByKey算子演示")
    val context = new SparkContext(conf)
    //====================================================
    val studentRDD: RDD[String] = context.textFile("spark/data/students.csv")

    val splitRDD: RDD[Array[String]] = studentRDD.map((s: String) => s.split(","))

    //需求：求出每个班级平均年龄
    //使用模式匹配的方式取出班级和年龄
    val clazzWithAgeRDD: RDD[(String, Int)] = splitRDD.map {
      case Array(_, _, age: String, _, clazz: String) => (clazz, age.toInt)
    }


    /**
     *  groupByKey: 按照键进行分组，将value值构成迭代器返回
     *  将来你在spark中看到RDD[(xx, xxx)] 这样的RDD就是kv键值对类型的RDD
     *  只有kv类型键值对RDD才可以调用groupByKey算子
     *
     */
    val kvRDD: RDD[(String, Iterable[Int])] = clazzWithAgeRDD.groupByKey()
    val clazzAvgAgeRDD: RDD[(String, Double)] = kvRDD.map {
      case (clazz: String, ageItr: Iterable[Int]) =>
        (clazz, ageItr.sum.toDouble / ageItr.size)
    }
    clazzAvgAgeRDD.foreach(println)

    while (true){

    }

    /**
     *  groupBy与groupByKey的区别（spark的面试题）
     *  1、代码上的区别：任意一个RDD都可以调用groupBy算子，只有kv类型的RDD才可以调用groupByKey
     *  2、groupByKey之后产生的RDD的结构比较简单，方便后续处理
     *  3、groupByKey的性能更好，执行速度更快，因为groupByKey相比较与groupBy算子来说，shuffle所需要的数据量较少
     */
  }
}
